package com.zee.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zee.admin.annotation.DataFilter;
import com.zee.admin.dao.SysUserDao;
import com.zee.admin.entity.SysUser;
import com.zee.admin.enums.SuperAdminEnum;
import com.zee.admin.model.dto.SysUserDTO;
import com.zee.admin.model.dto.SysUserQueryDTO;
import com.zee.admin.model.excel.SysUserExcel;
import com.zee.admin.model.response.AdminCode;
import com.zee.admin.model.vo.SysUserVO;
import com.zee.admin.service.ISysDeptService;
import com.zee.admin.service.ISysRoleUserService;
import com.zee.admin.service.ISysUserService;
import com.zee.admin.shiro.AdminSecurityUser;
import com.zee.admin.shiro.AdminUserDetail;
import com.zee.common.exception.ExceptionCast;
import com.zee.common.model.response.CommonCode;
import com.zee.common.utils.ConvertUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUser> implements ISysUserService {
    @Autowired
    private ISysRoleUserService sysRoleUserService;
    @Autowired
    private ISysDeptService sysDeptService;

    @Override
    public SysUserVO getById(Integer id) {
        return baseMapper.getById(id);
    }

    @Override
    public Page<SysUserVO> page(SysUserQueryDTO dto) {

        AdminUserDetail user = AdminSecurityUser.getUser();
        HashMap<String, Object> params = (HashMap<String, Object>) BeanUtil.beanToMap(dto);
        //普通管理员，只能查询所属部门及子部门的数据
        if (user.getSuperAdmin() == SuperAdminEnum.NO.value()) {
            params.put("deptIdList", sysDeptService.getSubDeptIdList(user.getDeptId(), true));
        }
        //查询
        return baseMapper.page(new Page<>(dto.getPage(), dto.getPageSize()), params);
    }

    @Override
    public Integer count(HashMap<String, Object> params) {
        AdminUserDetail user = AdminSecurityUser.getUser();
        //普通管理员，只能查询所属部门及子部门的数据
        if (user.getSuperAdmin() == SuperAdminEnum.NO.value()) {
            params.put("deptIdList", sysDeptService.getSubDeptIdList(user.getDeptId(), true));
        }

        Long count = baseMapper.selectCount(getWrapper(params));
        return Math.toIntExact(count);
    }

    @Override
    public List<SysUserExcel> exportList(HashMap<String, Object> params) {
        AdminUserDetail user = AdminSecurityUser.getUser();

        if (user.getSuperAdmin() == SuperAdminEnum.NO.value()) {
            params.put("deptIdList", sysDeptService.getSubDeptIdList(user.getDeptId(), true));
        }
        List<SysUserVO> sysUserVOList = baseMapper.list(params);
        return ConvertUtil.sourceToTarget(sysUserVOList, SysUserExcel.class);
    }

    private LambdaQueryWrapper<SysUser> getWrapper(Map<String, Object> params) {
        String username = (String) params.get("username");
        Integer gender = ConvertUtil.emptyStringToNull(params.get("gender"));
        Integer deptId = ConvertUtil.emptyStringToNull(params.get("deptId"));
        List<Integer> deptIdList = (List<Integer>) params.get("deptIdList");

        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(username), SysUser::getUsername, username);
        wrapper.eq(gender != null, SysUser::getGender, gender);
        wrapper.eq(deptId != null, SysUser::getDeptId, deptId);
        wrapper.in(deptIdList != null, SysUser::getDeptId, deptIdList);

        return wrapper;
    }

    @Override
    public SysUser getByUsername(String username) {
        SysUser sysUser = baseMapper.getByUsername(username);
        return sysUser;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(SysUserDTO dto) {
        //用户名查重
        SysUser byUsername = this.getByUsername(dto.getUsername());
        if (byUsername != null) {
            ExceptionCast.cast(AdminCode.USER_NAME_IS_EXIST);
        }
        SysUser sysUser = ConvertUtil.sourceToTarget(dto, SysUser.class);

        //密码加密
        String password = DigestUtils.sha256Hex(sysUser.getPassword());
        sysUser.setPassword(password);

        //保存用户
        sysUser.setSuperAdmin(SuperAdminEnum.NO.value());
        this.save(sysUser);

        //保存角色用户关系
        sysRoleUserService.saveRoleUser(sysUser.getId(), dto.getRoleIdList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysUserDTO dto) {
        SysUserVO dbUser = this.getById(dto.getId());
        if (dbUser == null) {
            ExceptionCast.cast(CommonCode.INVALID_PARAM);
        }

        SysUser sysUser = ConvertUtil.sourceToTarget(dto, SysUser.class);
        //密码加密
        if (StringUtils.isBlank(dto.getPassword())) {
            sysUser.setPassword(dbUser.getPassword());
        } else {
            String password = DigestUtils.sha256Hex(sysUser.getPassword());
            sysUser.setPassword(password);
        }

        //更新用户
        this.updateById(sysUser);

        //更新角色用户关系
        sysRoleUserService.saveRoleUser(sysUser.getId(), dto.getRoleIdList());
    }

    @Override
    public void delete(List<Integer> idList) {
        //判断是否有超级管理员Id
        Integer count = this.getCountBySuperAdmin(idList);
        if (count > 0) {
            ExceptionCast.cast(AdminCode.CAN_NOT_DELETE_SUPER_ADMIN);
        }
        this.removeByIds(idList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePassword(Integer id, String newPassword) {
        newPassword = DigestUtils.sha256Hex(newPassword);

        baseMapper.updatePassword(id, newPassword);
    }

    @Override
    public int getCountByDeptId(Integer deptId) {
        return baseMapper.getCountByDeptId(deptId);
    }

    @Override
    public List<Integer> getUserIdListByDeptId(List<Integer> deptIdList) {
        return baseMapper.getUserIdListByDeptId(deptIdList);
    }

    @Override
    public Integer getCountBySuperAdmin(List<Integer> idList) {
        return baseMapper.getCountBySuperAdmin(idList);
    }

    @Override
    @DataFilter
    public List<SysUser> test(HashMap<String, Object> map) {
        return baseMapper.test(map);
    }

}
